﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraBars;
using ProgramMain.Database;
using ProgramMain.Framework;
using ProgramMain.Google;

namespace ProgramMain.OpticNet
{
    public partial class VertexList : ProgramMain.Framework.BaseGridListCtl
    {
        public Coordinate nearCoordinate = null;
        public int coordinateTolerance;

        private bool m_AutoCreateDataset = true;
        public bool AutoCreateDataset
        {
            get { return m_AutoCreateDataset; }
            set { m_AutoCreateDataset = value; }
        }

        private bool _visibleConnector = true;
        public bool VisibleConnector
        {
            get { return _visibleConnector; }
            set
            {
                _visibleConnector = value;
                biConnection.Visibility = _visibleConnector
                                              ? DevExpress.XtraBars.BarItemVisibility.Always
                                              : DevExpress.XtraBars.BarItemVisibility.Never;
            }
        }

        public bool AutoCloseDetail { get; set; }

        public List<int> GetVertexesID(bool isNewOnly)
        {
            List<int> res = new List<int>(from q in this.m_simpleOpticNetDB.Vertexes where (isNewOnly && q.ID < 0) || !isNewOnly select q.ID);
           return res;
        }

        public class AcceptChangesArgs : EventArgs
        {
            private SimpleOpticNetDB.VertexesDataTable _dataTable;
            public SimpleOpticNetDB.VertexesDataTable DataTable
            {
                get
                {
                    return _dataTable;
                }
            }

            public AcceptChangesArgs(SimpleOpticNetDB.VertexesDataTable pDataTable)
            {
                _dataTable = pDataTable;
            }
        }

        public event EventHandler<AcceptChangesArgs> OnAcceptChanges;

        public int? CurveElemrntID { get; set; }

        public int? FibreID { get; set; }

        private List<SimpleOpticNetDB.VertexesRow> _vertexesFromCableTunnel = new List<SimpleOpticNetDB.VertexesRow>();

        //  private SimpleOpticNetDB.VertexesRow _tmp_DeleteVertex = null;
        private Database.SimpleOpticNetDB m_simpleOpticNetDB = null;

        public Database.SimpleOpticNetDB SimpleOpticNetDB
        {
            get { return m_simpleOpticNetDB; }
            set
            {
                m_simpleOpticNetDB = value;
                this.dataSource.DataMember = "Vertexes";
                this.dataSource.DataSource = this.m_simpleOpticNetDB;
            }
        }

        public bool AddVisible
        {
            get { return biAdd.Visibility == BarItemVisibility.Always; }
            set { biAdd.Visibility = value == true ? BarItemVisibility.Always : BarItemVisibility.Never; }
        }

        public VertexList()
        {
            InitializeComponent();
        }

        public SimpleOpticNetDB.VertexesRow AddVertex(Coordinate coordinate)
        {
            if (!CheckSecurityEditAction()) return null;
            dataSource.MoveLast();
            VertexDetail dialog = new VertexDetail();
            dialog.AutoClose = AutoCloseDetail;
            dialog.dataSource = dataSource;
            dialog.dataSource.AddNew();
            SimpleOpticNetDB.VertexesRow row = (SimpleOpticNetDB.VertexesRow)((DataRowView)dialog.dataSource.Current).Row;

            row.Longitude = Convert.ToDecimal(coordinate.Longitude);
            row.Latitude = Convert.ToDecimal(coordinate.Latitude);
            row.CaptionX = 15;
            row.CaptionY = 15;
            DialogResult dlgRes = dialog.ShowModal(BaseModalDetailCtl.ShowModeTypes.Add);
            if (dlgRes == DialogResult.OK)
            {
                if (OnAcceptChanges != null) OnAcceptChanges(this, new AcceptChangesArgs(m_simpleOpticNetDB.Vertexes));
                return row;
            }
            return null;

        }

        protected override void LoadData()
        {
            if (AutoCreateDataset && m_simpleOpticNetDB == null)
            {
                SimpleOpticNetDB = new SimpleOpticNetDB();
            }
            //прочитать данные из базы и заполнить датасет
            this.vertexesTableAdapter.SelectCommandTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
            if (FibreID.HasValue)
            {
                this.vertexesTableAdapter.ClearBeforeFill = true;
                this.vertexesTableAdapter.Fill(this.m_simpleOpticNetDB.Vertexes, null, null, null, null, null, null, FibreID, null, null);
            }
            else if (CurveElemrntID.HasValue)
            {
                this.vertexesTableAdapter.ClearBeforeFill = true;
                this.vertexesTableAdapter.Fill(this.m_simpleOpticNetDB.Vertexes, null, CurveElemrntID, null, null, null, null, null, true, null);
            }
            else if (DetailID.HasValue)
            {
                this.vertexesTableAdapter.ClearBeforeFill = true;
                this.vertexesTableAdapter.Fill(this.m_simpleOpticNetDB.Vertexes, DetailID, null, null, null, null, null, null, null, null);
            }
            else if (nearCoordinate != null)
            {
                this.vertexesTableAdapter.ClearBeforeFill = true;
                this.vertexesTableAdapter.Fill(this.m_simpleOpticNetDB.Vertexes, null, null,
                                               (decimal)nearCoordinate.Longitude, (decimal)nearCoordinate.Latitude, coordinateTolerance, null, null, null, null);


            }
            else
            {
                this.vertexesTableAdapter.ClearBeforeFill = true;
                this.vertexesTableAdapter.Fill(this.m_simpleOpticNetDB.Vertexes, null, null, null, null, null, null, null, null, null);
            }

            UpdateStatusText(this.m_simpleOpticNetDB.Vertexes);
        }

        protected override void UpdateData()
        {
            //внести изменения в базу
            this.vertexesTableAdapter.SetUpdateTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
            this.vertexesTableAdapter.Update(this.m_simpleOpticNetDB.Vertexes);
            UpdateStatusText(this.m_simpleOpticNetDB.Vertexes);
        }

        public event EventHandler<EventUpdateRow> EUpdateDataRow;

        public event EventHandler<EventUpdateRow> EDeleteDataRow;

        public event EventHandler<GlobalData.ListEventArgs> EBeforeDataRow;

        public event EventHandler<EventUpdateRow> EAfterDataRow;

        override protected void PostCreateDetailDialog(BaseModalDetailCtl.ShowModeTypes pShowMode, DataRow Row, DialogResult dialogResult)
        {
            if (dialogResult == DialogResult.OK && pShowMode == BaseModalDetailCtl.ShowModeTypes.Delete)
            {
                if (Row is SimpleOpticNetDB.VertexesRow)
                {
                    SimpleOpticNetDB.VertexesRow _tmp_DeleteVertex = (SimpleOpticNetDB.VertexesRow)Row;
                    _vertexesFromCableTunnel.Remove(_tmp_DeleteVertex);
                    OnDeleteDataRow(new EventUpdateRow(_tmp_DeleteVertex.ID, _tmp_DeleteVertex.ID));
                }
            }

        }

        protected override void AfterChangeDetailDialog(BaseModalDetailCtl.ShowModeTypes pShowMode, DataRowView RowView)
        {
            base.AfterChangeDetailDialog(pShowMode, RowView);

            if (EAfterDataRow != null) EAfterDataRow(this, null);
        }

        protected override void CancelChangeDetailDialog(BaseModalDetailCtl.ShowModeTypes pShowMode, DataRowView RowView)
        {
            if (EAfterDataRow != null) EAfterDataRow(this, null);
        }

        protected void OnUpdateDataRow(EventUpdateRow e)
        {
            if (e != null && EUpdateDataRow != null)
            {
                EUpdateDataRow.Invoke(this, e);
            }
        }

        protected void OnDeleteDataRow(EventUpdateRow e)
        {
            if (e != null && EDeleteDataRow != null)
            {
                EDeleteDataRow.Invoke(this, e);
            }
        }

        protected override void Action_Delete(object sender, EventArgs e)
        {
            if (!AutoCreateDataset)
            {
                if (dataSource.Count > 0)
                {
                    SimpleOpticNetDB.VertexesRow _tmp_DeleteVertex =
                        (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;

                }
            }
            base.Action_Delete(sender, e);
        }

        public void UpdateDataRow()
        {

            dataSource.MoveFirst();
            int count = this.dataSource.Count;
            for (int index = 0; index < count; index++)
            {
                dataSource.Position = index;
                SimpleOpticNetDB.VertexesRow row = (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
                int dsId = row.ID;
                if (row.ID < 0)
                    vertexesTableAdapter.Update(row);
                int DBId = row.ID;
                if (dsId < 0 && DBId > 0)
                {
                    OnUpdateDataRow(new EventUpdateRow(dsId, DBId));
                }
            }
            dataSource.MoveLast();

        }

        override protected BaseModalDetailCtl CreateDetailDialog(BaseModalDetailCtl.ShowModeTypes pShowMode)
        {
            if (EBeforeDataRow != null) EBeforeDataRow(this, new GlobalData.ListEventArgs(GetVertexesID(true)));
            return new VertexDetail();
        }

        protected override void biDetails_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (dataSource.Current != null)
            {
                SimpleOpticNetDB.VertexesRow row = (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
                FrmOpticMap map = FrmOpticMap.ShowForm();
                map.SetCenterMapObject(row.Longitude, row.Latitude);
                map.AddVertesLighted(row.ID);
            }
        }

        public bool AutoAddCableTunnel(SimpleOpticNetDB.VertexesRow row)
        {
            if (_faindVertexesFromCableTunnel(row)) return false;
            _vertexesFromCableTunnel.Add(row);
            this.vertexesTableAdapter.ClearBeforeFill = false;
            this.vertexesTableAdapter.Fill(m_simpleOpticNetDB.Vertexes, row.ID, null, null, null, null, null, null, null, null);
            dataSource.MoveLast();
            return true;
        }

        private bool _faindVertexesFromCableTunnel(SimpleOpticNetDB.VertexesRow row)
        {
            var vertexes = from query in _vertexesFromCableTunnel where query.Latitude == row.Latitude && query.Longitude == row.Longitude select query;
            return vertexes.Count() > 0;
        }

        public void GetVertexesTerminated(out int? vertex1ID, out int? vertex2ID)
        {
            var vertexes = from query in _vertexesFromCableTunnel select query;
            if (vertexes.Count() > 0)
            {
                vertex1ID = vertexes.First().ID;
                vertex2ID = vertexes.Last().ID;
            }
            else
            {
                vertex1ID = null;
                vertex2ID = null;
            }
        }

        public void EditCoordinateNewVertex(int ObjectID, Coordinate coordinate)
        {
            SimpleOpticNetDB.VertexesRow row = FindVertex(ObjectID);
            if (row != null && coordinate != null)
            {
                row.Longitude = (decimal)coordinate.Longitude;
                row.Latitude = (decimal)coordinate.Latitude;
                dataSource.EndEdit();
                if (OnAcceptChanges != null) OnAcceptChanges(this, new AcceptChangesArgs(m_simpleOpticNetDB.Vertexes));
            }
        }
        public void DeleteVertex(int vertexID)
        {
            FindVertex(vertexID);
            biDelete.PerformClick();
        }
        public SimpleOpticNetDB.VertexesRow FindVertex(int vertexID)
        {
            int v = this.dataSource.Find("ID", vertexID);
            if (v > -1)
            {
                dataSource.Position = v;
                SimpleOpticNetDB.VertexesRow row = (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
                return row;
            }
            else
            {
                return null;
            }
        }

        public void EditNewVertex(int vertexID)
        {
            if (FindVertex(vertexID) != null)
            {
                biEdit.PerformClick();
            }
        }

        public void ConnectionVertexes()
        {
            for (int index = 0; index < dataSource.Count; index++)
            {
                dataSource.Position = index;
                if (!ConnectionInVertex()) return;
            }
        }

        public bool ConnectionInVertex()
        {
            SimpleOpticNetDB.VertexesRow vertexesRow =
                (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
            if (vertexesRow != null)
            {
                FrmVertexMap.ShowForm(false, vertexesRow.ID);
            }
            return true;
        }

        protected override void biConnection_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            if (dataSource.Count > 0)
                ConnectionInVertex();
        }

        protected override void biVertexMap_ItemClick(object sender, ItemClickEventArgs e)
        {
            SimpleOpticNetDB.VertexesRow vertexesRow =
                 (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
            if (vertexesRow != null)
            {
                FrmVertexMap.ShowForm(false, vertexesRow.ID);
            }
        }

        private void gridControl_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.F10 && CheckSecurityEditAction())
            {
                for (int i = 0; i < dataSource.Count; i++)
                {
                    dataSource.Position = i;
                    SimpleOpticNetDB.VertexesRow vertexesRow = (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
                    if (vertexesRow != null)
                    {
                        if (vertexesRow.IsAddressNull())
                        {
                            Coordinate coordinate = new Coordinate(vertexesRow.Longitude, vertexesRow.Latitude);
                            GoogleSearch.GoogleSearch search = new GoogleSearch.GoogleSearch(coordinate);
                            List<GoogleSearch.SearchResult> results = search.Search();
                            if (results.Count > 0)
                            {
                                vertexesRow.Address = search.AddressFormat(results[0]);
                                vertexesRow.EndEdit();

                            }
                        }
                    }
                }
                //vertexesTableAdapter.Update();
                UpdateData();
            }
        }

        protected override void biAddDocument_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (dataSource.Current != null)
            {
                SimpleOpticNetDB.VertexesRow row = (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
                new DocumentList() { VertexID = row.ID }.AddDocument();

            }
        }

        protected override void biDocumentList_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (dataSource.Current != null)
            {
                SimpleOpticNetDB.VertexesRow row = (SimpleOpticNetDB.VertexesRow)((DataRowView)dataSource.Current).Row;
                new FrmDocumentList() { VertexID = row.ID }.ShowDialog();
            }
        }
    }
}